﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using Microsoft.Win32;
using System.Data;

namespace XMLDataEditor
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DS = null;
            DT = null;
            LastPath = string.Empty;
            FileName = string.Empty;

            this.cbTable.IsEnabled = false;
            title = this.Title;
        }
		
		public DataSet DS;
        public DataTable DT;
        public String LastPath;
        public String FileName;
        private string title;
        private bool IsChanged;
        private bool InSubTable = false;
        private List<int> SubTableIndex;


		private void cmdOpen_Executed(object sender, ExecutedRoutedEventArgs e)
		{
            if (IsChanged)
            {
                MessageBoxResult res = MessageBox.Show("数据已修改，是否在退出前保存？", "当前文件即将关闭", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
                if (res == MessageBoxResult.Cancel)
                {
                    return;
                }
                else if (res == MessageBoxResult.Yes)
                {
                    SaveDataSetToFile();
                    IsChanged = false;
                }
            }

			OpenFileDialog dialog = new OpenFileDialog();
			dialog.Title = "打开XML数据集文件";
			dialog.Filter = "数据集XML文件(*.xml)|*.xml";
			dialog.DefaultExt = "xml";
			dialog.AddExtension = true;
			dialog.CheckFileExists = true;
			dialog.CheckPathExists = true;
            
            if (String.IsNullOrEmpty(LastPath))
            {
                LastPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            }

            dialog.InitialDirectory = LastPath;
			
			bool? result;
			result = dialog.ShowDialog();
			
			if (result != null && (bool)result)
			{
				FileName = dialog.FileName;
                LastPath = System.IO.Path.GetDirectoryName(FileName);
			}
			else
			{
				return;	
			}

            if (fillDataSetFromFile(FileName))
            {
                bindDataSet();
                this.Title = title + " - " + FileName;
            }
            else
            {
                clearDataSet();
                this.Title = title;
            }

            IsChanged = false;
		}

        public bool fillDataSetFromFile(string filename)
        {
            try
            {
                DS = new DataSet();
                DS.ReadXml(filename);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace,
                    "读取数据集文件失败",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return false;
            }

            return true;
        }

        public bool bindDataSet()
        {
            try
            {
                cbTable.DataContext = DS.Tables;
                cbTable.DisplayMemberPath = "TableName";
                cbTable.SelectedValuePath = "TableName";
                cbTable.IsEnabled = true;

                if (cbTable.Items.Count > 0)
                {
                    cbTable.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace,
                    "刷新列表失败",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return false;
            }

            return true;
        }

        public void clearDataSet()
        {
            dgMain.DataContext = null;
            cbTable.DataContext = null;
            cbTable.IsEnabled = false;
        }

        private void cbTable_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (DS != null && cbTable.SelectedIndex != -1)
            {
                string tableName = cbTable.SelectedItem.ToString();

                DT = DS.Tables[tableName];
                dgMain.DataContext = DT;
                DT.RowChanged += new DataRowChangeEventHandler(MainWindow_RowChanged);
                DT.RowDeleted += new DataRowChangeEventHandler(MainWindow_RowChanged);

                InSubTable = false;
            }
        }

        private void cmdSave_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (!String.IsNullOrEmpty(FileName))
            {
                if (SaveDataSetToFile())
                    this.Title = title + " - " + FileName;
            }

        }

        private bool SaveDataSetToFile()
        {
            if (!IsChanged)
                return true;

            try
            {
                DS.WriteXml(FileName, XmlWriteMode.WriteSchema);
                IsChanged = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace,
                    "保存文件失败",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return false;
            }

            return true;
        }

        private void btCommit_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (DS != null && cbTable.SelectedIndex != -1 && tbRule.Text.Length > 0)
                {
                    if (InSubTable)
                        cbTable_SelectionChanged(sender, null);

                    string tableName = cbTable.SelectedItem.ToString();

                    DT.RowChanged -= MainWindow_RowChanged;
                    DT.RowDeleted -= MainWindow_RowChanged;

                    DataTable table = DT.Clone();
                    DataRow[] Rows = DS.Tables[tableName].Select(tbRule.Text);

                    SubTableIndex = new List<int>();

                    foreach (DataRow row in Rows)
                    {
                        table.ImportRow(row);
                        SubTableIndex.Add(DT.Rows.IndexOf(row));
                    }

                    dgMain.DataContext = table;

                    table.RowChanged += new DataRowChangeEventHandler(SubTable_RowChanged);
                    table.RowDeleting += new DataRowChangeEventHandler(SubTable_RowChanged);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message,"无法执行" , MessageBoxButton.OK, MessageBoxImage.Asterisk);
            }
        }
        
        private void MainWindow_RowChanged(object sender, DataRowChangeEventArgs e)
        {
            IsChanged = true;
            this.Title = title + " - " + FileName + "*";
        }

        private void SubTable_RowChanged(object sender, DataRowChangeEventArgs e)
        {
            try
            {
                switch (e.Action)
                {
                    case DataRowAction.Add:
                        DT.ImportRow(e.Row);
                        SubTableIndex.Add(DT.Rows.Count - 1);
                        break;
                    case DataRowAction.Delete:
                        {
                            int i = ((DataTable)dgMain.DataContext).Rows.IndexOf(e.Row);
                            int index = SubTableIndex[i];
                            DT.Rows.RemoveAt(index);
                        }
                        break;
                    case DataRowAction.Change:
                        {
                            int i = ((DataTable)dgMain.DataContext).Rows.IndexOf(e.Row);
                            int index = SubTableIndex[i];
                            for (int j = 0; j < e.Row.ItemArray.Length; j++)
                                DT.Rows[index][j] = e.Row[j];
                        }
                        break;
                }

                IsChanged = true;
                this.Title = title + " - " + FileName + "*";
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "无法执行", MessageBoxButton.OK, MessageBoxImage.Asterisk);
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (IsChanged)
            {
                MessageBoxResult result = MessageBox.Show("数据已修改，是否在退出前保存？", "窗口即将关闭", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
                if (result == MessageBoxResult.Cancel)
                {
                    e.Cancel = true;
                }
                else if (result == MessageBoxResult.Yes)
                {
                    SaveDataSetToFile();
                    e.Cancel = false;
                }
                else
                {
                    e.Cancel = false;
                }
            }
        }

        private void btCancel_Click(object sender, RoutedEventArgs e)
        {
            cbTable_SelectionChanged(sender, null);
        }

        private void cmdListTablename_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (!String.IsNullOrEmpty(FileName))
            {
                string text = string.Empty;
                foreach (DataTable dt in DS.Tables)
                {
                    text += (dt.TableName.ToString() + "\n");
                }

                //DlgListTablename dialog = new DlgListTablename(text);
                DlgListTablename dialog = new DlgListTablename(DS);
                dialog.Owner = this;
                dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                dialog.ShowDialog();


            }
        }

        private void cmdTableClear_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(FileName))
                return;

            try
            {
                DT.Rows.Clear();
                IsChanged = true;
                this.Title = title + " - " + FileName + "*";
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "无法执行", MessageBoxButton.OK, MessageBoxImage.Asterisk);
            }
        }

        private void dgMain_CellEditEnding(object sender, Microsoft.Windows.Controls.DataGridCellEditEndingEventArgs e)
        {
            if (InSubTable)
            {
                SubTable_RowChanged(sender, null);
            }
            else
            {
                MainWindow_RowChanged(sender, null);
            }
        }

        private void cmdRefresh_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (!String.IsNullOrEmpty(FileName))
            {
                if (IsChanged)
                {
                    MessageBoxResult res = MessageBox.Show("数据已修改，刷新则放弃修改，是否继续？", "当前文件即将刷新", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
                    if (res == MessageBoxResult.Cancel || res == MessageBoxResult.No)
                    {
                        return;
                    }
                }

                string current_tablename = cbTable.SelectedItem.ToString();
                string current_filter = tbRule.Text;

                if (fillDataSetFromFile(FileName))
                {
                    bindDataSet();
                    this.Title = title + " - " + FileName;
                }
                else
                {
                    clearDataSet();
                    this.Title = title;
                }

                foreach (Object item in cbTable.Items)
                {
                    if (item.ToString() == current_tablename)
                    {
                        cbTable.SelectedItem = item;
                        break;
                    }
                }

                if (!string.IsNullOrEmpty(current_filter))
                    btCommit_Click(null, null);

                IsChanged = false;
            }

        }

    }
}
